﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SQLite;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace MiniTennis
{
    public partial class FrmMiniTennis : Form
    {
        private SQLiteConnection ObjConnection;
        String Usuario;
        Graphics grafico;
        tabla mytabla = new tabla() { X = 100, Y=300, tamaño = new Size(60,10), direccion_x = 1, speed = 15};

        tabla mytablared = new tabla() { X = 100, Y = 50, tamaño = new Size(60, 10), direccion_x = 1, speed = 15 };

        Bola mybola = new Bola() { X = 50, Y = 100, tamaño = new Size(20, 20), direccion_x = 1, direccion_Y = 1, speed = 10 };



        int puntaje = 0;
        int puntajered = 0;

        bool multiplayer =true;

        string _mensajeChat1;
        NetworkStream streamServidor;
        TcpClient cliente;



        private Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private Thread thread;



        public FrmMiniTennis(String Usu, SQLiteConnection ObjConn)
        {
            InitializeComponent();
            Usuario = Usu;
            grafico = CreateGraphics();
            DoubleBuffered = true;          
            ObjConnection = ObjConn;
        }

        public void inicializar_juego()
        {
             mytabla.X = 100;
             mytabla.Y = 300;

             mytablared.X = 100;
             mytablared.Y = 50;


             mybola.X = 50;
             mybola.Y = 100;
             mybola.direccion_x = 1;
             mybola.direccion_Y= 1;



             puntaje = 0;
             puntajered = 0;

             this.lbl_puntaje.Text = "0";
        }

        private void timer1_Tick(object sender, EventArgs e)
        {            
            grafico.FillRectangle(Brushes.White, mytabla.rectangulo);           
            movimiento_tabla();        
            grafico.FillRectangle(Brushes.Black, mytabla.rectangulo);          

            

            grafico.FillEllipse(Brushes.White, mybola.rectangulo);
            movimiento_bola();
            colision_bola_paredes();
            grafico.FillEllipse(Brushes.Red, mybola.rectangulo);

            colision_bola_tabla();


            string texto = Usuario + "|" + mytabla.X.ToString() + "|" + mybola.direccion_x.ToString() + "|" + mybola.direccion_Y.ToString();
            byte[] buffer = Encoding.ASCII.GetBytes(texto);
            clientSocket.Send(buffer);



           // if (multiplayer)
               // colision_bola_tablared();
        }

        public void colision_bola_paredes() {
            if (mybola.X == 0)
                mybola.direccion_x = 1;
            if (mybola.X == Width-30)
                mybola.direccion_x = 0;
            if (mybola.Y == 40)
                mybola.direccion_Y = 1;
            if (mybola.Y == Height-50)
                mybola.direccion_Y = 0;
        }

        public void colision_bola_tabla() {

            if (mybola.rectangulo.IntersectsWith(mytabla.rectangulo))
            {
                puntaje += 1;

                this.lbl_puntaje.Text = puntaje.ToString();

                if (mybola.direccion_Y == 0)
                    mybola.direccion_Y = 1;

                if (mybola.direccion_Y == 1)
                    mybola.direccion_Y = 0;               
            }
        }

        public void colision_bola_tablared()
        {

            if (mybola.rectangulo.IntersectsWith(mytablared.rectangulo))
            {
                puntajered += 1;

               // this.lbl_puntaje.Text = puntaje.ToString();     

                //MessageBox.Show(mybola.Y.ToString());  

                if (mybola.direccion_Y == 1)
                    mybola.direccion_Y = 0;

                if (mybola.direccion_Y == 0)
                    mybola.direccion_Y = 1;

               

                
            }
        }

        public void movimiento_tabla() {

          //  if (mybola.Y < mytabla.Y + 20)
          //  {
                if (mytabla.direccion_x == 1)
                {
                    if (mytabla.X < Width - 78)
                        mytabla.X += mytabla.speed;
                }
                if (mytabla.direccion_x == 0)
                {
                    if (mytabla.X > 0)
                        mytabla.X -= mytabla.speed;
                }
            //}
        }

        public void movimiento_tablared()
        {

            if (mybola.Y > mytablared.Y)
            {
                if (mytablared.direccion_x == 1)
                {
                    if (mytablared.X < Width - 78)
                        mytablared.X += mytablared.speed;
                }
                if (mytablared.direccion_x == 0)
                {
                    if (mytablared.X > 0)
                        mytablared.X -= mytablared.speed;
                }
            }
        }

        public void movimiento_bola() {

         //   if ((mybola.Y < mytabla.Y + 20) && (multiplayer == true && mybola.Y > mytablared.Y-10))
         //   {
                if (mybola.direccion_x == 1)
                    mybola.X += mybola.speed;
                if (mybola.direccion_x == 0)
                    mybola.X -= mybola.speed;
                if (mybola.direccion_Y == 1)                
                    mybola.Y += mybola.speed;                
                if (mybola.direccion_Y == 0)
                    mybola.Y -= mybola.speed;
         //   }
          //  else {


             /*   this.lbl_finjuego.Visible = true;
                this.label1.Visible = true;
                this.lbl_puntaje.Visible = true;
                this.lbl_puntaje.Text = puntaje.ToString();
                this.timer1.Enabled = false;

                DateTime hoy = DateTime.Today;

                String Sql = "INSERT INTO partidas (par_usu_id,par_puntaje,par_fecha) values ('" + Usuario + "'," + puntaje.ToString() + ",'" + hoy.ToString("d") + "')";
                Ejecutar_consulta(Sql);
              */

          //  }

        }

        private void FrmMiniTennis_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Right)
                mytabla.direccion_x = 1;
            if (e.KeyCode == Keys.Left)
                mytabla.direccion_x = 0;

            //tabla red

        /*    if (e.KeyCode == Keys.D)
                mytablared.direccion_x = 1;
            if (e.KeyCode == Keys.A)
                mytablared.direccion_x = 0;
         */ 
         
        }

        private void iniciarPartidaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.lbl_finjuego.Visible = false;
            this.label1.Visible = false;
            this.lbl_puntaje.Visible = false;
            grafico.FillRectangle(Brushes.White, mytabla.rectangulo);
            grafico.FillRectangle(Brushes.White, mytablared.rectangulo);
            grafico.FillEllipse(Brushes.White, mybola.rectangulo);
            inicializar_juego();
            this.timer1.Enabled = true;
        }


        private void Ejecutar_consulta(string txtQuery)
        {
            ObjConnection.Open();
            SQLiteCommand ObjCommand = new SQLiteCommand(ObjConnection);
            ObjCommand.CommandText = txtQuery;
            ObjCommand.ExecuteNonQuery();
            ObjConnection.Close();
        }

        private void salirToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void iniciarPartidaEnRedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmServidor Server = new FrmServidor();
            Server.Show();
           // this.Hide();
        }

        private void conectarseAUnaPartidaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmConectar Connect = new FrmConectar(Usuario,this);
            Connect.Show();
        }

        public void conectar(String ip, String Puerto)
        {
            try
            {

                this.Text = string.Format("Cliente: {0}", Usuario);

               // _mensajeChat1 = "Conectando al servidor...";
               // Mensaje1();

                cliente = new TcpClient(ip, int.Parse(Puerto));

                streamServidor = cliente.GetStream();

                Byte[] datos = System.Text.Encoding.ASCII.GetBytes(Usuario + "$");

                streamServidor.Write(datos, 0, datos.Length);
                streamServidor.Flush();

                Thread ctThread = new Thread(Chat);
                ctThread.Start();

               // btnConectar.Enabled = false;
               // btnEnviar.Enabled = true;
            }
            catch (Exception ex)
            {
               // txtChat.Text = ex.ToString();

              /*  if (MessageBox.Show("¿Conectar de nuevo?") == System.Windows.Forms.DialogResult.Yes)
                    btnConectar_Click(null, null);
                else
                    this.Close(); */
            }
        }

        private void Mensaje1()
        {
            if (this.InvokeRequired)
                this.Invoke(new MethodInvoker(Mensaje1));
            else {
                MessageBox.Show(_mensajeChat1);

                if (_mensajeChat1.Trim() == "Iniciar_Partida")
                {
                    this.multiplayer = true;
                    this.inicializar_juego();

                    this.lbl_finjuego.Visible = false;
                    this.label1.Visible = false;
                    this.lbl_puntaje.Visible = false;
                    grafico.FillRectangle(Brushes.White, mytabla.rectangulo);
                    grafico.FillRectangle(Brushes.White, mytablared.rectangulo);
                    grafico.FillEllipse(Brushes.White, mybola.rectangulo);
                    inicializar_juego();
                    this.timer1.Enabled = true;

                }

                //txtChat.Text = txtChat.Text + Environment.NewLine + " -> " + _mensajeChat1;
            }
                
        }

        private void Chat()
        {
            while (true)
            {
                streamServidor = cliente.GetStream();

                byte[] bytes = new byte[256];

                streamServidor.Read(bytes, 0, bytes.Length);

                _mensajeChat1 = Encoding.ASCII.GetString(bytes);
                Mensaje1();
            }
        }

        private void FrmMiniTennis_Load(object sender, EventArgs e)
        {
            thread = new Thread(new ThreadStart(WorkThreadFunction));
            thread.Start();
        }

        public void WorkThreadFunction()
        {
            try
            {
                if (multiplayer)
                {

                    clientSocket.Connect(IPAddress.Loopback, 100);

                    string texto = "ID|" + Usuario;
                    byte[] buffer = Encoding.ASCII.GetBytes(texto);
                    clientSocket.Send(buffer);

                    while (true)
                    {
                        byte[] receivedBuffer = new byte[1024];
                        int received = clientSocket.Receive(receivedBuffer);
                        byte[] data = new byte[received];
                        Array.Copy(receivedBuffer, data, received);
                        MethodInvoker action = delegate
                        {
                            string dataReceived = Encoding.ASCII.GetString(data);
                            char[] separador = { '$' };
                            string[] textoSplit = dataReceived.Split(separador, StringSplitOptions.RemoveEmptyEntries);

                            if (textoSplit.Length > 1)
                            {
                                char[] sep = { '|' };
                                string[] jugador1 = textoSplit[0].Split(sep, StringSplitOptions.RemoveEmptyEntries);
                                string[] jugador2 = textoSplit[1].Split(sep, StringSplitOptions.RemoveEmptyEntries);


                                grafico.FillRectangle(Brushes.White, mytablared.rectangulo);
                               
                                   

                                if (jugador1[0] != Usuario)
                                {
                                    mytablared.X = Convert.ToInt32(jugador1[1]);

                                }
                                else
                                {
                                    mytablared.X = Convert.ToInt32(jugador2[1]);
                                }

                                grafico.FillRectangle(Brushes.Black, mytablared.rectangulo);
                            }
                            else {
                                if ((textoSplit.Length > 0) && (textoSplit[0].ToString() == "Iniciar"))
                                {
                                    this.multiplayer = true;
                                    this.inicializar_juego();

                                    this.lbl_finjuego.Visible = false;
                                    this.label1.Visible = false;
                                    this.lbl_puntaje.Visible = false;                                  

                                    grafico.FillRectangle(Brushes.White, mytabla.rectangulo);
                                    grafico.FillRectangle(Brushes.White, mytablared.rectangulo);
                                    grafico.FillEllipse(Brushes.White, mybola.rectangulo);
                                    inicializar_juego();
                                    this.timer1.Enabled = true;
                                
                                }
                            
                            }
                        };
                          textBox1.BeginInvoke(action);
                        //label1.Text = Encoding.ASCII.GetString(data);
                    }
                }
            }
            catch (Exception x)
            {
            }
        }
        
    }
}
